
package com.compuvest.web;

// <editor-fold defaultstate="collapsed" desc="import">
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;

import java.text.DecimalFormat;
// </editor-fold>

public class Basket implements java.io.Serializable {

// <editor-fold defaultstate="collapsed" desc="init variables">
    public static final double WA_TAX_FEE = 0.095; // 9.5%
    public static final double SIGNATURE_PRICE = 2.00;

    public static final String IMAGE_10_BACKS = "<img src='./img/ad/nextag.jpg' alt=''/>";
    public static final String IMAGE_FROOGLE_FREE_SHIPPING = "<img src='./img/ad/froogle.jpg' alt=''/>";

    private final Map<Integer,ItemsInBasket> contents;
    private Customer customer;

    private String paymentMethod = "";
    private double shippingCost = 0d;
    private String shipCode = "";
    private String shipDesc = "";
    private double taxCost = 0d;
    private double grandTotal = 0d;
    private int orderid = 0;
    private String orderNumber = "0";
    private String orderDate = "";
    private String notes = "";
    private boolean reseller = false;
    private boolean blindShipping = false;
    private boolean signatureRequired = false;

    private final CompuvestCookies cookies;

    private PromotionCode promotionCode;
    private Coupon coupon;

    private String amazonId = "";
// </editor-fold>

    public Basket() {
        contents = new HashMap<>();
        cookies = new CompuvestCookies();
    }

    public Customer getCustomer()                       { return customer; }
    public void setCustomer(Customer customer)		{ this.customer = customer; }

    public boolean getReseller()                        { return reseller; }
    public void setReseller(boolean reseller)		{ this.reseller = reseller; }

    public boolean getBlindShipping()                   { return blindShipping; }
    public void setBlindShipping(boolean blindShipping)	{ this.blindShipping = blindShipping; }

    public boolean getSignatureRequired()		{ return signatureRequired; }
    public void setSignatureRequired(boolean signature)	{ this.signatureRequired = signature; }

    public double getSignaturePrice()                   { return SIGNATURE_PRICE; }
    public String getPaymentMethod()                    { return paymentMethod; }
    public void setPaymentMethod(String paymentMethod)	{ this.paymentMethod = paymentMethod; }

    public double getShippingCost()                     { return shippingCost; }
    public void setShippingCost(double shippingCost)	{ this.shippingCost = shippingCost; }

    public String getShippingCode()			{ return shipCode; }
    public void setShippingCode(String shipCode)	{ this.shipCode = cleanString(shipCode); }

    public String getShippingDescription()              { return shipDesc; }
    public void setShippingDescription(String shipDesc)	{ this.shipDesc = cleanString(shipDesc); }

    public int getOrderID()                             { return orderid; }
    public void setOrderID(int orderid)                 { this.orderid = orderid; }

    public String getOrderNumber()                      { return orderNumber; }
    public void setOrderNumber(String orderNumber)	{ this.orderNumber = orderNumber; }

    public String getOrderDate()                        { return orderDate; }
    public void setOrderDate(String orderDate)		{ this.orderDate = orderDate; }

// tax for WA = 0.95
    public double getTaxCost()                          { return taxCost; }
    public void setTaxCost(double taxCost)              { this.taxCost = taxCost; }

    public String getNotes()                            { return notes; }
    public void setNotes(String notes)                  { this.notes = cleanString(notes); }

    public String getAmazonId()                         { return amazonId; }
    public void setAmazonId(String amazonId)            { this.amazonId = amazonId; }

// <editor-fold defaultstate="collapsed" desc="cleanString()">

    private String cleanString(String str) {
	return str == null ? "" : str.trim();
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Coupons Show">

    public Coupon getCoupon()               { return coupon; }
    public void setCoupon(Coupon coupon)    { this.coupon = coupon; }

    private String advertImage = null;
    public String getCouponShow(AdvertShow advert) {

        // do this only one time
	if(advertImage == null) {
            String advName = getCompuvestCookies().getAdvertSite();
            int advertid = advert.getAdvertID(advName);
            switch(advertid) {
                case AdvertShow.NEXTTAG:
                    setCoupon(new Coupon(10.00, 30, "N")); // price, days, prefix
                    advertImage = IMAGE_10_BACKS;
                    break;
                case AdvertShow.GRABBER:
                    setCoupon(new Coupon(10.00, 30, "G"));
                    advertImage = IMAGE_10_BACKS;
                    break;
                case AdvertShow.SHOPING:
                    setCoupon(new Coupon(10.00, 30, "S"));
                    advertImage = IMAGE_10_BACKS;
                    break;
                default:
                    advertImage = "";
                    break;
            }
            // free shipping for froogle and all googleXX + cws + cwm + bing
            if(advert.isFreeShipping(advName)) {
                advertImage = IMAGE_FROOGLE_FREE_SHIPPING;
            }
	}
	return advertImage;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="getCompuvestCookies()">

    public CompuvestCookies getCompuvestCookies()	{ return cookies; }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="getContents()">

    public ArrayList<ItemsInBasket> getContents() {
        return new ArrayList<>(contents.values());
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Promotion">
// Coupon price for all items in basket

    public PromotionCode getPromotion() { return promotionCode; }
    public void setPromotion(PromotionCode promocode) {

	if(promocode != null) {
            // delete all other item promotion code
            ItemsInBasket item;
            for(int itemid : contents.keySet()) {
		item = contents.get(itemid);

		item.setPromoProcent(0d);
		item.setPromoCode("");
            }
	}
	this.promotionCode = promocode;
    }

    public String getCouponMessage(boolean needShow) {

	if(promotionCode == null) return "";

        String couponMessage = "";
        if(promotionCode.getPromoPrice() != 0d && getTotal(false) >= promotionCode.getPromoPrice()) {
            couponMessage = String.format("Discount coupon (CV%s) : -$%.2f", promotionCode.getPromoCoupon(), promotionCode.getPromoPrice());
        }
        else if(promotionCode.getProcent() != 0d) {
            couponMessage = String.format("Discount coupon (CV%s) : -%.2f%%", promotionCode.getPromoCoupon(), promotionCode.getProcent());
        }
        else {
            if(needShow) {
                couponMessage = "<p style='color:red;font-size:11px;'>Warning: The total value  of  items in the basket must exceed a value of coupon you use!</p>";
            }
        }
	return couponMessage;
    }

    public String getCouponPayPalMessage() {

	if(promotionCode == null) return "";

        String couponMessage = "";
        if(promotionCode.getPromoPrice() != 0d && getTotal(false) >= promotionCode.getPromoPrice()) {
            couponMessage = String.format("<input type='hidden' name='discount_amount_cart' value='%.2f'/>", promotionCode.getPromoPrice());
        }
        else if(promotionCode.getProcent() != 0d) {
            couponMessage = String.format("<input type='hidden' name='discount_rate_cart' value='%.2f'/>", promotionCode.getProcent());
        }
	return couponMessage;
    }

    public double getCouponPromotionAmazon() {

	if(promotionCode == null) return 0d;

        double promo = 0d;
        double total = getTotal(false);
        if(promotionCode.getPromoPrice() != 0d && total >= promotionCode.getPromoPrice()) {
            promo = promotionCode.getPromoPrice();
        }
        else if(promotionCode.getProcent() != 0d) {
            promo = total / 100 * promotionCode.getProcent();
        }
	return promo;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="addItem()">

    public void addItem(ItemsInBasket item) {

        int itemID = item.getItemID();
        if(contents.containsKey(itemID)) {
            ItemsInBasket itemInCart = contents.get(itemID);
            item.setTotalQuantity(item.getTotalQuantity() + itemInCart.getTotalQuantity());

            if( !item.getStock()) { // test on no more quantity
                if(item.getQuantity() < item.getTotalQuantity()) {
                    item.setTotalQuantity(item.getQuantity());
                }
            }
        }
        contents.put(itemID, item);
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="setQuantity()">

    public void setQuantity(int itemID, int quantity, String warranty) {

        if(!contents.containsKey(itemID)) return;
        else if(quantity <= 0) {
            contents.remove(itemID);
            return;
        }

        // update quiantity
        ItemsInBasket item = contents.get(itemID);
        if(!item.getStock()) { // Check quantity on MAXimum
            if(item.getQuantity() < quantity)
            quantity = item.getQuantity();
        }
        else { // check hackers(no more than 999 ea.)
            if(999 < quantity) quantity = 999;
        }
        item.setTotalQuantity(quantity);

        // set warranty
        if(warranty != null) {
            int pos = warranty.indexOf('|');
            if(pos != -1) {
                double warrantyPrice = 0d;
                try {
                    warrantyPrice = Double.parseDouble(warranty.substring(pos + 1, warranty.length()));
                } catch(NumberFormatException ignore) { }

                item.setWarrantyPrice(warrantyPrice);
                item.setWarrantyDesc(warranty.substring(0, pos));
            }
        }
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="checkPromotionCode()">

    public boolean checkPromotionCode(String customerPromoCode) {

	// if have basket coupon not able use items promotion code delete them
	if(promotionCode != null) return false;

        ItemsInBasket item;
        for(int itemid : contents.keySet()) {
            item = contents.get(itemid);

            if(item.getPromotionCode() != null) {
		Double promoProcent = item.getPromotionCode().get(customerPromoCode);
		if(promoProcent != null) {
                    item.setPromoProcent(promoProcent);
                    item.setPromoCode(customerPromoCode); // for count use promocode -> orderfinish
                    return true;
		}
            }
	}
        return false;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="getTotal()">

    public double getTotal(boolean useCoupon) {

        double total = 0d;
        ItemsInBasket item;
        for(int itemid : contents.keySet()) {
            item = contents.get(itemid);
            total += (double)item.getTotalQuantity() * item.getSellPrice() + item.getWarrantyTotal();
        }
        if(useCoupon && promotionCode != null) {
            // total cannot be less than promo price
            if(promotionCode.getPromoPrice() != 0 && total >= promotionCode.getPromoPrice()) {
                total -= promotionCode.getPromoPrice();
            }
            // discount basket in procent
            if(promotionCode.getProcent() != 0) {
                total = total - (total * (promotionCode.getProcent() / 100d));
            }
        }

        return total;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="[gs]etGrandTotal()">

    public double getGrandTotal()                   { return grandTotal; }
    public void setGrandTotal(double grandTotal)    { this.grandTotal = grandTotal; }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="getTotalWeight()">

    public double getTotalWeight() {

        double totalWeight = 0d;
        ItemsInBasket item;
        for(int itemid : contents.keySet()) {
            item = contents.get(itemid);
            totalWeight += (double)item.getTotalQuantity() * item.getWeight();
        }
        return totalWeight;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="clean()">

    public void clean()	{
        this.contents.clear();
        this.paymentMethod = "";
        this.shippingCost = 0d;
        this.taxCost = 0d;
        this.grandTotal = 0d;
        this.reseller = false;
	this.promotionCode = null;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="getCountItems()">

    public int getCountItems()	{ return contents.size(); }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="notEmpty()">

    public boolean notEmpty()	{ return !contents.isEmpty(); }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="isEmpty()">

    public boolean isEmpty()	{ return contents.isEmpty(); }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="roundTwoDecimals()">

    public double roundTwoDecimals(double d) {

        DecimalFormat twoDForm = new DecimalFormat("#.##");
        return Double.valueOf(twoDForm.format(d));
}
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="toString()">

    @Override
    public String toString() {

        StringBuilder buf = new StringBuilder();
        buf.append("---------------------------");
        buf.append("\ncontents: ").append(contents);
        buf.append("\ncustomer: ").append(customer);
        buf.append("\npaymentMethod: ").append(paymentMethod);
        buf.append("\nshippingCost: ").append(shippingCost);
        buf.append("\nshipCode: ").append(shipCode);
        buf.append("\nshipDesc: ").append(shipDesc);
        buf.append("\ntaxCost: ").append(taxCost);
        buf.append("\ngrandTotal: ").append(grandTotal);
        buf.append("\norderid: ").append(orderid);
        buf.append("\norderNumber: ").append(orderNumber);
        buf.append("\norderDate: ").append(orderDate);
        buf.append("\nnotes: ").append(notes);
        buf.append("\nreseller: ").append(reseller);
        buf.append("\nblindShipping: ").append(blindShipping);
        buf.append("\nsignatureRequired: ").append(signatureRequired);
        buf.append("\npromotionCode: ").append(promotionCode);
        buf.append("\ncoupon: ").append(coupon);
        buf.append("\n---------------------------");
        return buf.toString();
    }
// </editor-fold>
}
